﻿// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "pch.h"
#include <tchar.h>
#include <string>
#include <iostream>
#include <fstream>
#include <windows.h>
using namespace std;


HINSTANCE hinstIdLib;
HINSTANCE hinstIcLib;
CVR_InitComm initComm;
CVR_CloseComm closeComm;
CVR_Authenticate authenticate;
CVR_Read_Content read_Content;
GetPeopleName getPeopleName;
GetPeopleIDCode getPeopleIDCode;

rf_init_def rf_init;
rf_exit_def rf_exit;
rf_load_key_def rf_load_key;
rf_card_def rf_card;
rf_read_def rf_read;
rf_authentication_def rf_authentication;
rf_halt_def rf_halt;
rf_beep_def rf_beep;


// add by xyang in 2022.5.9 desc 写卡句柄
rf_write_def rf_write;

// add by xyang in 2022.8.13 desc 复位句柄
rf_reset_def rf_reset;

// add by xyang in 2022.11.3 desc 寻卡句柄
rf_request_def rf_request;
rf_anticoll_def rf_anticoll;
rf_select_def rf_select;
getTagTypeDef getTagType;
getSnrDef getSnr;

bool id_dll_loaded = false;
bool is_id_device_ready = false;

int icdev = 0;
bool ic_dll_loaded = false;
bool is_ic_device_ready = false;

TCHAR dll_base[MAX_PATH] = { 0 };
unsigned char chKey[16] = { 'P', 'U', 'B', '1', '1', 'A', 0x08, 0x77, 0x8F, 0x69, 'B', 'U', 'P', 'Z', 'Y', 'B' };
unsigned char chKey2[16] = { '8', '8', '8', '8', '8', '8', 0x08, 0x77, 0x8F, 0x69, 'Y', 'T', 'A', '9', '8', 'B' };

unsigned char oldChKey[16] = { '8', '8', '8', '8', '8', '8', 0xFF, 0x07, 0x80, 0x69, '8', '8', '8', '8', '8', '8' };

DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE,
	0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
#define   GUID_CLASS_USB_DEVICE                   GUID_DEVINTERFACE_USB_DEVICE  

DEFINE_GUID(GUID_DEVINTERFACE_USB_HUB,
	0xf18a0e88, 0xc30c, 0x11d0, 0x88, 0x15, 0x00, 0xa0, 0xc9, 0x06, 0xbe, 0xd8);
#define		GUID_CLASS_USB_HUB GUID_DEVINTERFACE_USB_HUB


BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
	TCHAR szBuffer[MAX_PATH] = { 0 };
	TCHAR termbLib[MAX_PATH] = { 0 };
	TCHAR mwrf32Lib[MAX_PATH] = { 0 };
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
		
		GetModuleFileName(hModule, szBuffer, sizeof(szBuffer) / sizeof(TCHAR) - 1);
		_tcsncpy_s(dll_base, szBuffer, (size_t)(_tcslen(szBuffer) - 18));

		_tcscat_s(termbLib, MAX_PATH, dll_base);
		_tcscat_s(termbLib, MAX_PATH, TEXT("Termb.dll"));

		_tcscat_s(mwrf32Lib, MAX_PATH, dll_base);
		_tcscat_s(mwrf32Lib, MAX_PATH, TEXT("MWRF32.dll"));

		hinstIdLib = LoadLibrary(termbLib);
		if (NULL != hinstIdLib) {
			initComm = (CVR_InitComm)GetProcAddress(hinstIdLib, "CVR_InitComm");
			closeComm = (CVR_CloseComm)GetProcAddress(hinstIdLib, "CVR_CloseComm");
			authenticate = (CVR_Authenticate)GetProcAddress(hinstIdLib, "CVR_Authenticate");
			read_Content = (CVR_Read_Content)GetProcAddress(hinstIdLib, "CVR_Read_Content");
			getPeopleName = (GetPeopleName)GetProcAddress(hinstIdLib, "GetPeopleName");
			getPeopleIDCode = (GetPeopleIDCode)GetProcAddress(hinstIdLib, "GetPeopleIDCode");

			id_dll_loaded = true;
			/*
			if (NULL != initComm && initComm(1001) == 1)
				is_id_device_ready = true;
			*/
		}

		hinstIcLib = LoadLibrary(mwrf32Lib);
		if (NULL != hinstIcLib) {
			rf_init = (rf_init_def)GetProcAddress(hinstIcLib, "rf_init");
			rf_exit = (rf_exit_def)GetProcAddress(hinstIcLib, "rf_exit");
			rf_load_key = (rf_load_key_def)GetProcAddress(hinstIcLib, "rf_load_key");
			rf_card = (rf_card_def)GetProcAddress(hinstIcLib, "rf_card");
			rf_read = (rf_read_def)GetProcAddress(hinstIcLib, "rf_read");
			rf_authentication = (rf_authentication_def)GetProcAddress(hinstIcLib, "rf_authentication");
			rf_halt = (rf_halt_def)GetProcAddress(hinstIcLib, "rf_halt");
			rf_beep = (rf_beep_def)GetProcAddress(hinstIcLib, "rf_beep");

			// add by xyang in 2022.5.9 desc 写卡句柄
			rf_write = (rf_write_def)GetProcAddress(hinstIcLib, "rf_write");

			rf_reset = (rf_reset_def)GetProcAddress(hinstIcLib, "rf_reset");

			rf_request = (rf_request_def)GetProcAddress(hinstIcLib, "rf_request");
			rf_anticoll = (rf_anticoll_def)GetProcAddress(hinstIcLib, "rf_anticoll");
			rf_select = (rf_select_def)GetProcAddress(hinstIcLib, "rf_select");
			// getTagType = (getTagTypeDef)GetProcAddress(hinstIcLib, "getTagType");
			// getSnr = (getSnrDef)GetProcAddress(hinstIcLib, "getSnr");
			ic_dll_loaded = true;
		}
		break; 
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
		break;
    case DLL_PROCESS_DETACH:
		if (is_id_device_ready && closeComm)
			closeComm();

		if (is_ic_device_ready && rf_exit && icdev >= 0)
			rf_exit(icdev);

		is_id_device_ready = false;
		is_ic_device_ready = false;
		FreeLibrary(hinstIdLib);
		FreeLibrary(hinstIcLib);
		id_dll_loaded = false;
		ic_dll_loaded = false;
        break;
    }
    return TRUE;
}

extern "C" _declspec(dllexport) int ForceReconnect() {
	is_id_device_ready = false;
	is_ic_device_ready = false;

	return 0;
}


extern "C" _declspec(dllexport) int rfCard(int icdev, string & path, unsigned long& snr_ret)
{
	int rst = -1;
	path.append(",RF_REQUEST");
	unsigned int tagType;
	int c = 3;
	while (c > 0 && rst != 0) {
		c = c - 1;
		rst = rf_request(icdev, 0, &tagType);
	}
	// 没有寻到卡, 判断是否是卡没移走, 重复刷导致的读卡
	if (rst != 0) {
		path.append(",NO_CARD");
		c = 3;
		while (c > 0 && rst != 0) {
			c = c - 1;
			rst = rf_request(icdev, 1, &tagType);
		}
		if (rst == 0) {
			path.append(",NO_MOVE_UP");
			return YICT_ERROR_NO_REMOVE_CARD;
		}
		else {
			path.append(",NO_PUT_CARD");
			return YICT_ERROR_CARD_NOT_FOUND;
		}
	}

	if (tagType == 0x0004) {
		path.append(", M1");
	}
	else {
		path.append(",ML");
	}

	// 卡防止冲突
	path.append(", RF_ANTICOLL");
	unsigned long snr;
	rst = rf_anticoll(icdev, 0, &snr);
	//path.append(", SNR" + snr);
	if (rst != 0) {
		return -4;
	}


	unsigned char size;
	rst = rf_select(icdev, snr, &size);
	//path.append(", SIZE" + size);
	if (rst != 0) {
		return -5;
	}
	snr_ret = snr;
	return 0;
}


extern "C" _declspec(dllexport) int rfCard1(int icdev, string & path, unsigned long& snr_ret)
{
	int rst = -1;
	path.append(",RF_REQUEST");
	unsigned int tagType;
	int c = 3;
	while (c > 0 && rst != 0) {
		c = c - 1;
		rst = rf_request(icdev, 1, &tagType);
	}
	// 没有寻到卡, 判断是否是卡没移走, 重复刷导致的读卡
	if (rst != 0) {
		path.append(",NO_CARD");
		path.append(",NO_PUT_CARD");
		return YICT_ERROR_CARD_NOT_FOUND;
	}

	if (tagType == 0x0004) {
		path.append(", M1");
	}
	else {
		path.append(",ML");
	}

	// 卡防止冲突
	path.append(", RF_ANTICOLL");
	unsigned long snr;
	rst = rf_anticoll(icdev, 0, &snr);
	//path.append(", SNR" + snr);
	if (rst != 0) {
		return -4;
	}


	unsigned char size;
	rst = rf_select(icdev, snr, &size);
	//path.append(", SIZE" + size);
	if (rst != 0) {
		return -5;
	}
	snr_ret = snr;
	return 0;
}

extern "C" _declspec(dllexport) int WriteCard(int port, unsigned  char* p8, unsigned  char* p9, char* resu) {
	int rst = 0;
	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];
	string path = "";
	unsigned char oldChKeyA[6];
	unsigned char oldChKeyB[6];

	unsigned char chKeyTwoA[6];
	unsigned char chKeyTwoB[6];


	if (!ic_dll_loaded || NULL == rf_init) {
		return YICT_ERROR_DLL_NOT_FOUND;
	}

	icdev = rf_init(port, 9600);
	path += ", INIT_9600";
	if (icdev < 0) {
		//任然连接不上,再返回 -777 连接失败
		return YICT_ERROR_DEVICE_PORT;
	}

	path += ", LOAD_KEY_888";

	// 装载旧密码, 有的读卡器是旧密码, 处理一下旧密码的情况
	memcpy(oldChKeyA, oldChKey, 6);
	memcpy(oldChKeyB, &oldChKey[10], 6);
	//rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
	if (rf_load_key(icdev, (short)0, 2, oldChKeyA) != 0 || rf_load_key(icdev, (short)4, 2, oldChKeyB) != 0) {
		path += ", LOAD_KEY_PUB";

		// 装配新密码
		memcpy(chKeyA, chKey2, 6);
		memcpy(chKeyB, &chKey2[10], 6);

		if (rf_load_key(icdev, (short)0, 1, chKeyA) != 0 || rf_load_key(icdev, (short)4, 1, chKeyB) != 0) {
			path += ", ERROR_KEY_A";
			if (icdev >= 0) {
				path += ",EXIT";
				//rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	path += ",RF_CARD";
	rst = rfCard1(icdev, path, cid);

	path += ",RF_AUTH";
	rst = rf_authentication(icdev, 4, 2);
	if (rst != 0) {
		rf_exit(icdev);
		icdev = rf_init(port, 9600);
		path += ", INIT_9600";
		// strcpy(resu, path.c_str());

		if (icdev < 0) {
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			//任然连接不上,再返回 -777 连接失败
			return YICT_ERROR_DEVICE_PORT;
			//}
		}

		// 填充新密码试试
		path += ", LOAD_NEW_KEYS";
		// 装配新密码
		memcpy(chKeyTwoA, chKey2, 6);
		memcpy(chKeyTwoB, &chKey2[10], 6);
		if (rf_load_key(icdev, (short)0, 2, chKeyTwoA) != 0 || rf_load_key(icdev, (short)4, 2, chKeyTwoB) != 0) {
			path += ", ERROR_KEY_B";

			// 退出读卡器
			if (icdev >= 0) {
				path += ",EXIT";
				// rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}


		rst = rfCard1(icdev, path, cid);
		rst = rf_authentication(icdev, 4, 2);
		if (rst != 0) {
			path += ",EXIT_AUTH";
			//rf_halt(icdev);
			rf_exit(icdev);
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_AUTH;
		}
	}

	if (rst != 0) {
		path += ",AUTH RST 0";
		//rf_halt(icdev);
		rf_exit(icdev);
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_AUTH;
	}
	path += ",RF_WRITE";
	if (rf_write(icdev, 9, p9) != 0 || rf_write(icdev, 8, p8) != 0) {
		//rf_halt(icdev);
		rf_exit(icdev);
		path += ",RF_EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_WRITE_CARD;
	}
	rf_halt(icdev);
	rf_exit(icdev);
	
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	return YICT_SUCC_WRITE_CARD;
}

extern "C" _declspec(dllexport) int GetIDCardInfo(int port, char *name, int *name_len, char* idcode, int *idcode_len) {
	int rst = 0;


	if (!is_id_device_ready && id_dll_loaded && NULL != initComm) {
		rst = initComm(port);
		switch (rst) {
		case 1:
			is_id_device_ready = true;
			break;
		case 2:
			return YICT_ERROR_DEVICE_PORT;
		default:
			return YICT_ERROR_DEVICE_PORT;
		}
	}

	if (is_id_device_ready) {
		rst = authenticate();
		switch (rst) {
		case 0:
			return YICT_ERROR_DLL_NOT_FOUND;
		case 1: {
			if (read_Content(1) == 1) {
				getPeopleName(name, name_len);
				getPeopleIDCode(idcode, idcode_len);

				return YICT_SUCC_READ_CARD;
			}
			return YICT_ERROR_READ_CARD;
		}
		case 2:
			return YICT_ERROR_CARD_NOT_FOUND;
		case 3:
			return YICT_ERROR_SELECT_CARD;
		case 4:
			is_id_device_ready = false;
			return YICT_ERROR_DEVICE_PORT;
		default:
			is_id_device_ready = false;
			return YICT_ERROR_UNKNOWN;
		}
	}
	else if (!id_dll_loaded) { return YICT_ERROR_DLL_NOT_FOUND; }
	else { return YICT_ERROR_UNKNOWN; }
}


extern "C" _declspec(dllexport) int ReadCard(int port, char* p8, int* p8_len, char* p9, int* p9_len, char* resu) {
	int rst = 0;

	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];
	string path = "";
	unsigned char oldChKeyA[6];
	unsigned char oldChKeyB[6];

	unsigned char chKeyTwoA[6];
	unsigned char chKeyTwoB[6];


	if (!ic_dll_loaded || NULL == rf_init) {
		return YICT_ERROR_DLL_NOT_FOUND;
	}

	icdev = rf_init(port, 9600);
	path += ", INIT_9600";
	if (icdev < 0) {
		//任然连接不上,再返回 -777 连接失败
		return YICT_ERROR_DEVICE_PORT;
	}
	 
	path += ", LOAD_KEY_888";

	// 装载旧密码, 有的读卡器是旧密码, 处理一下旧密码的情况
	memcpy(oldChKeyA, oldChKey, 6);
	memcpy(oldChKeyB, &oldChKey[10], 6);
	//rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
	if (rf_load_key(icdev, (short)0, 2, oldChKeyA) != 0 || rf_load_key(icdev, (short)4, 2, oldChKeyB) != 0) {
		path += ", LOAD_KEY_PUB";

		// 装配新密码
		memcpy(chKeyA, chKey, 6);
		memcpy(chKeyB, &chKey[10], 6);

		if (rf_load_key(icdev, (short)0, 1, chKeyA) != 0 || rf_load_key(icdev, (short)4, 1, chKeyB) != 0) {
			path += ", ERROR_KEY_A";
			if (icdev >= 0) {
				path += ",EXIT";
				rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	path += ",RF_CARD";
	rst = rfCard1(icdev, path, cid);

	path += ",RF_AUTH";
	rst = rf_authentication(icdev, 0, 2);
	if (rst != 0) {
		rf_exit(icdev);
		icdev = rf_init(port, 9600);
		path += ", INIT_9600";
		// strcpy(resu, path.c_str());

		if (icdev < 0) {
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			//任然连接不上,再返回 -777 连接失败
			rf_halt(icdev);
			rf_exit(icdev);
			return YICT_ERROR_DEVICE_PORT;
			//}
		}

		// 填充新密码试试
		path += ", LOAD_NEW_KEYS";
		// 装配新密码
		memcpy(chKeyTwoA, chKey2, 6);
		memcpy(chKeyTwoB, &chKey2[10], 6);
		if (rf_load_key(icdev, (short)0, 2, chKeyTwoA) != 0 || rf_load_key(icdev, (short)4, 2, chKeyTwoB) != 0) {
			path += ", ERROR_KEY_B";

			// 退出读卡器
			if (icdev >= 0) {
				path += ",EXIT";
				rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}


		rst = rfCard1(icdev, path, cid);
		rst = rf_authentication(icdev, 0, 2);
		if (rst != 0) {
			path += ",EXIT_AUTH";
			rf_halt(icdev);
			rf_exit(icdev);
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_AUTH;
		}
	}

	if (rst != 0) {
		path += ",AUTH RST 0";
		rf_halt(icdev);
		rf_exit(icdev);
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_AUTH;
	}
	path += ",RF_READ";

	if (rf_read(icdev, 8, (unsigned char*)p8) != 0 || rf_read(icdev, 9, (unsigned char*)p9) != 0){
		path += ", READ_UN_SUCCESS,EXIT";
		rf_halt(icdev);
		rf_exit(icdev);
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return 407;
	};
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	rf_beep(icdev, (short)10);
	*p8_len = strlen(p8); 
	*p9_len = strlen(p9);
			
	rf_halt(icdev);
	rf_exit(icdev);
	return YICT_SUCC_READ_CARD;
}

extern "C" _declspec(dllexport) int xexit(int code) {
	if (icdev > 0) {
		rf_exit(icdev);
		icdev = -1;
		return 1;
	};
	return 0;
}


extern "C" _declspec(dllexport) int GetICCardInfoNotHalt(int port, char* card_id, int* card_id_len, char* permit_no, int* permit_no_len, char* resu, char* no_halt) {
	int rst = 0;
	string path = "";
	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];


	unsigned char oldChKeyA[6];
	unsigned char oldChKeyB[6];

	unsigned char chKeyTwoA[6];
	unsigned char chKeyTwoB[6];

	if (!ic_dll_loaded || NULL == rf_init) {
		return YICT_ERROR_DLL_NOT_FOUND;
	}

	icdev = rf_init(port, 9600);
	//path += ", PORT_VALUE";
	//path += port;
	path += ", HALT_VALUE";
	path += no_halt;
	path += ", INIT_9600";
	// strcpy(resu, path.c_str());

	if (icdev < 0) {
		//9600 连接不上,再用115200尝试连接
		// icdev = rf_init(port, 115200);
		//if (icdev < 0) {
			//任然连接不上,再返回 -777 连接失败
		return YICT_ERROR_DEVICE_PORT;
		//}
	}

	path += ", LOAD_KEY_888";
	//strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

	int old_pass = 1;
	// 装载旧密码, 有的读卡器是旧密码, 处理一下旧密码的情况
	memcpy(oldChKeyA, oldChKey, 6);
	memcpy(oldChKeyB, &oldChKey[10], 6);
	//rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
	if (rf_load_key(icdev, (short)0, 1, oldChKeyA) != 0 || rf_load_key(icdev, (short)4, 1, oldChKeyB) != 0) {
		path += ", LOAD_KEY_PUB";

		old_pass = 0;
		// 装配新密码
		memcpy(chKeyA, chKey, 6);
		memcpy(chKeyB, &chKey[10], 6);

		if (rf_load_key(icdev, (short)0, 1, chKeyA) != 0 || rf_load_key(icdev, (short)4, 1, chKeyB) != 0) {
			path += ", ERROR_KEY_A";
			if (icdev >= 0) {
				path += ",HALT";
				path += ",EXIT";
				rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	//rst = rf_card(icdev, (short)0, &cid);
	//path += to_string(rst);
	rst = rfCard(icdev, path, cid);
	if (rst != 0) {
		rf_halt(icdev);
		rf_exit(icdev);
		path += ",HALT";
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return rst;
	}

	path += ",RF_AUTH";
	rst = rf_authentication(icdev, 0, 1);
	if (rst != 0) {
		//rf_halt(icdev);
		path += ",EXIT";
		rf_exit(icdev);
		icdev = rf_init(port, 9600);
		path += ", INIT_9600";
		// strcpy(resu, path.c_str());

		if (icdev < 0) {
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			//任然连接不上,再返回 -777 连接失败
			rf_halt(icdev);
			rf_exit(icdev);
			path += ",HALT";
			path += ",EXIT";
			return YICT_ERROR_DEVICE_PORT;
			//}
		}

		// 填充新密码试试
		path += ", LOAD_NEW_KEYS";
		// 装配新密码
		memcpy(chKeyTwoA, chKey, 6);
		memcpy(chKeyTwoB, &chKey[10], 6);
		if (rf_load_key(icdev, (short)0, 1, chKeyTwoA) != 0 || rf_load_key(icdev, (short)4, 1, chKeyTwoB) != 0) {
			path += ", ERROR_KEY_B";

			// 退出读卡器
			if (icdev >= 0) {
				path += ",HALT";
				path += ",EXIT";
				rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}

		path += ",RF_CARD";
		// rst = rf_card(icdev, (short)0, &cid);
		// path += to_string(rst);
		rst = rfCard(icdev, path, cid);
		if (rst != 0) {
			rf_halt(icdev);
			rf_exit(icdev);
			path += ",HALT";
			path += ",EXIT";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return rst;
		}
		rst = rf_authentication(icdev, 0, 1);
		if (rst != 0) {
			path += ",EXIT_AUTH";
			rf_halt(icdev);
			rf_exit(icdev);
			path += ",HALT";
			path += ",EXIT";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_AUTH;
		}
	}

	if (rst != 0) {
		path += ",AUTH RST 0";
		rf_halt(icdev);
		rf_exit(icdev);
		path += ",HALT";
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_AUTH;
	}
	path += ",RF_READ";
	rst = rf_read(icdev, 4, (unsigned char*)permit_no);
	if (rst == 0) {
		_ultoa_s(cid, card_id, 16, 10);
		*card_id_len = strlen(card_id);
		*permit_no_len = strlen(permit_no);
		//path += ",RF_HALT";
		//rf_halt(icdev);
		rf_exit(icdev);
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_SUCC_READ_CARD;
	}


	if (icdev >= 0) {
		path += ",EXIT";
		//rf_halt(icdev);
		path += ",EXIT";
		rf_exit(icdev);
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return 407;
	}
	//rf_halt(icdev);
	rf_exit(icdev);
	path += ",EXIT";
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	return 408;
}


extern "C" _declspec(dllexport) int GetICCardInfo(int port, char* card_id, int* card_id_len, char* permit_no, int* permit_no_len, char* resu, char* no_halt) {
	int rst = 0;
	string path = "";
	unsigned long cid = 0;
	unsigned char chKeyA[6];
	unsigned char chKeyB[6];


	unsigned char oldChKeyA[6];
	unsigned char oldChKeyB[6];

	unsigned char chKeyTwoA[6];
	unsigned char chKeyTwoB[6];
	
	if (!ic_dll_loaded || NULL == rf_init) {
		return YICT_ERROR_DLL_NOT_FOUND;
	}

	icdev = rf_init(port, 9600);
	//path += ", PORT_VALUE";
	//path += port;
	path += ", HALT_VALUE";
	path += no_halt;
	path += ", INIT_9600";
	// strcpy(resu, path.c_str());

	if (icdev < 0) {
		//9600 连接不上,再用115200尝试连接
		// icdev = rf_init(port, 115200);
		//if (icdev < 0) {
			//任然连接不上,再返回 -777 连接失败
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		//rf_reset(icdev, 60);
		//rf_halt(icdev);

		//rf_exit(icdev);
		return icdev;
		//}
	}

	path += ", LOAD_KEY_888";
	//strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());

	int old_pass = 1;
	// 装载旧密码, 有的读卡器是旧密码, 处理一下旧密码的情况
	memcpy(oldChKeyA, oldChKey, 6);
	memcpy(oldChKeyB, &oldChKey[10], 6);
	//rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
	rst = rf_load_key(icdev, (short)0, 1, oldChKeyA);
	rst = rf_load_key(icdev, (short)4, 1, oldChKeyB);
	if (rst != 0) {
		path += rst;
		path += ", LOAD_KEY_PUB";

		old_pass = 0;
		// 装配新密码
		memcpy(chKeyA, chKey, 6);
		memcpy(chKeyB, &chKey[10], 6);
		rst = rf_load_key(icdev, (short)0, 1, chKeyA);
		rst = rf_load_key(icdev, (short)4, 1, chKeyB);
		if (rst != 0) {
			path += rst;
			path += ", ERROR_KEY_A";
			if (icdev >= 0) {
				path += ",HALT";
				path += ",EXIT";
				rf_halt(icdev);
				rf_exit(icdev);
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYA;
		}
	}

	//rst = rf_card(icdev, (short)0, &cid);
	//path += to_string(rst);
	rst = rfCard(icdev, path, cid);
	if (rst != 0) {
		rf_halt(icdev);
		rf_exit(icdev);
		path += ",HALT";
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return rst;
	}

	path += ",RF_AUTH";
	rst = rf_authentication(icdev, 0, 1);
	if (rst != 0) {
		rf_exit(icdev);
		path += ",EXIT";
		icdev = rf_init(port, 9600);
		path += ", INIT_9600";
		// strcpy(resu, path.c_str());

		if (icdev < 0) {
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
				//任然连接不上,再返回 -777 连接失败
			rf_halt(icdev);
			rf_exit(icdev);
			path += ",HALT";
			path += ",EXIT";
			return YICT_ERROR_DEVICE_PORT;
			//}
		}

		// 填充新密码试试
		path += ", LOAD_NEW_KEYS";
		// 装配新密码
		memcpy(chKeyTwoA, chKey, 6);
		memcpy(chKeyTwoB, &chKey[10], 6);
		if (rf_load_key(icdev, (short)0, 1, chKeyTwoA) != 0 || rf_load_key(icdev, (short)4, 1, chKeyTwoB) != 0) {
			path += ", ERROR_KEY_B";
			
			// 退出读卡器
			if (icdev >= 0) {
				rf_halt(icdev);
				rf_exit(icdev);
				path += ",HALT";
				path += ",EXIT";
			}
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_LOAD_KEYB;
		}

		path += ",RF_CARD";
		// rst = rf_card(icdev, (short)0, &cid);
		// path += to_string(rst);
		rst = rfCard(icdev, path, cid);
		if (rst != 0) {
			rf_halt(icdev);
			rf_exit(icdev);
			path += ",HALT";
			path += ",EXIT";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return rst;
		}
		rst = rf_authentication(icdev, 0, 1);
		if (rst != 0) {
			path += ",EXIT_AUTH";
			rf_halt(icdev);
			rf_exit(icdev);
			path += ",HALT";
			path += ",EXIT";
			strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
			return YICT_ERROR_AUTH;
		}
	}

	if (rst != 0) {
		path += ",AUTH RST 0";
		rf_halt(icdev);
		rf_exit(icdev);
		path += ",HALT";
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_ERROR_AUTH;
	}
	path += ",RF_READ";
	rst = rf_read(icdev, 4, (unsigned char*)permit_no);
	if (rst == 0) {
		_ultoa_s(cid, card_id, 16, 10);
		*card_id_len = strlen(card_id);
		*permit_no_len = strlen(permit_no);
		path += ",RF_HALT";
		rf_halt(icdev);
		rf_exit(icdev);
		path += ",HALT";
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return YICT_SUCC_READ_CARD;
	}


	if (icdev >= 0) {
		path += ",EXIT";
		rf_halt(icdev);
		rf_exit(icdev);
		path += ",HALT";
		path += ",EXIT";
		strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
		return 407;
	}
	rf_halt(icdev);
	rf_exit(icdev);
	path += ",HALT";
	path += ",EXIT";
	strcpy_s(resu, strlen(path.c_str()) + 1, path.c_str());
	return 408;
}

extern "C" _declspec(dllexport) void getDevices(char *devs) {
	//LPGUID lpGuid = (LPGUID)&GUID_CLASS_USB_DEVICE;//
	LPGUID lpGuid = (LPGUID)&GUID_CLASS_USB_HUB;//
	int INTERFACE_DETAIL_SIZE = 1024;
	int nCount = 0;
	HDEVINFO info = SetupDiGetClassDevs(lpGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);

	//enumerate device information  
	DWORD required_size = 0;
	int i;
	SP_DEVINFO_DATA DeviceInfoData = { sizeof(DeviceInfoData) };

	DWORD DataT;
	DWORD buffersize = 1024;
	DWORD req_bufsize = 0;

	for (i = 0; SetupDiEnumDeviceInfo(info, i, &DeviceInfoData); i++) {
		WCHAR *did = new WCHAR[1024];
		WCHAR *locid = new WCHAR[1024];
		WCHAR *locdesc = new WCHAR[1024];
		//get device description information
		if (!SetupDiGetDeviceInstanceId(info, &DeviceInfoData, (PTSTR)did, buffersize, &req_bufsize))
			continue;
		if (!SetupDiGetDeviceRegistryPropertyW(info, &DeviceInfoData, SPDRP_LOCATION_PATHS, &DataT, (LPBYTE)locid, buffersize, &req_bufsize))
			continue;

		if (!SetupDiGetDeviceRegistryPropertyW(info, &DeviceInfoData, SPDRP_LOCATION_INFORMATION, &DataT, (LPBYTE)locdesc, buffersize, &req_bufsize))
			continue;
	}

	//strcat(devs, )
	SetupDiDestroyDeviceInfoList(info);
}
